package com.ff.xyh.service.post.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ff.xyh.common.entity.post.PostReply;
import com.ff.xyh.common.entity.result.ResultObject;
import com.ff.xyh.common.vo.post.PostReplyBaseInfo;
import com.ff.xyh.common.vo.post.PostReplyVo;
import com.ff.xyh.common.qo.post.PostReplyQuery;
import com.ff.xyh.service.post.mapper.PostReplyMapper;
import com.ff.xyh.service.post.service.PostReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 帖子回复表 服务实现类
 * </p>
 *
 * @author ff
 * @since 2022-10-26
 */
@Service
public class PostReplyServiceImpl extends ServiceImpl<PostReplyMapper, PostReply> implements PostReplyService {

    @Override
    public List<PostReplyVo> getPostReplieVoListByPostIdAndPostType(String postId, Integer postType) {
//        List<PostReplyVo> result = new ArrayList<>();
        // 获取帖子的子集回复
        QueryWrapper<PostReply> wrapper = new QueryWrapper<>();
        wrapper
                .eq("post_id", postId)
                .eq("post_type", postType)
                .ne("parent_id", 0)
                .lt("complaint_number", 10) // 举报数要小于10
                .orderByAsc("gmt_created");
        List<PostReply> postReplies = this.baseMapper.selectList(wrapper);
        List<PostReplyVo> result = this.getFinalPostReplyVoList(postReplies);
        if (result == null || result.isEmpty()) {

            List<PostReply> firstPostRepliesByPostIdAndPostType = this.getFirstPostRepliesByPostIdAndPostType(postId, postType);
            List<PostReplyBaseInfo> firstPostReplyBaseInfoList = new ArrayList<>(firstPostRepliesByPostIdAndPostType.size());
            for (PostReply postReply : firstPostRepliesByPostIdAndPostType) {
                PostReplyBaseInfo postReplyBaseInfo = new PostReplyBaseInfo();
                BeanUtils.copyProperties(postReply, postReplyBaseInfo);
                firstPostReplyBaseInfoList.add(postReplyBaseInfo);
            }

            if (firstPostReplyBaseInfoList == null || firstPostReplyBaseInfoList.isEmpty()) {
                return null;
            }
            result = new ArrayList<>();
            for (PostReplyBaseInfo replyBaseInfo : firstPostReplyBaseInfoList) {
                PostReplyVo replyVo = new PostReplyVo();
                replyVo.setFirstReply(replyBaseInfo); // 设置一级回复
                result.add(replyVo);
            }
        }
        if (result == null || result.isEmpty()) {
            return null;
        }
        return result;
    }

    @Override
    public List<PostReply> getFirstPostRepliesByPostIdAndPostType(String postId, Integer postType) {
        QueryWrapper<PostReply> wrapper = new QueryWrapper<>();
        wrapper.eq("post_id", postId)
                .eq("post_type", postType)
                .eq("parent_id", 0)
                .lt("complaint_number", 10) // 举报数要小于10
                .orderByAsc("gmt_created");
        List<PostReply> postReplies = baseMapper.selectList(wrapper);

        if (postReplies.isEmpty())
            return null;
        else
            return postReplies;
    }

    /**
     * 获取帖子下的所有回复
     * @param postReplyQuery
     * @return
     */
    @Override
    public ResultObject getPostReplyCondition(PostReplyQuery postReplyQuery) {

        Page<PostReply> page = new Page<>(postReplyQuery.getCurrentPage(), postReplyQuery.getPageSize());
        QueryWrapper<PostReply> wrapper = new QueryWrapper<>();

        if (postReplyQuery.getGmtAfter() != null) {
            wrapper.ge("gmt_created", postReplyQuery.getGmtAfter());
        }
        if (postReplyQuery.getGmtBefore() != null) {
            wrapper.le("gmt_created", postReplyQuery.getGmtBefore());
        }

        // 按创建时间排序意味着要最新
        if (postReplyQuery.getOrderByCreatedTime() != null && postReplyQuery.getOrderByCreatedTime()) {
            // 降序
            wrapper.orderByDesc("gmt_created");
        } else {
            wrapper.orderByAsc("gmt_created");
        }

        if (!StringUtils.isEmpty(postReplyQuery.getPostId())) {
            wrapper.eq("post_id", postReplyQuery.getPostId());
        }
        if (postReplyQuery.getPostType() != null) {
            wrapper.eq("post_type", postReplyQuery.getPostType());
        }

        // 先获取帖子所有子回复
        wrapper.ne("parent_id", 0);
        List<PostReply> childrenReplyList = this.list(wrapper);

        // 先获取一级回复
        wrapper.eq("parent_id", 0);

        IPage<PostReply> resultPage = this.page(page, wrapper);

        List<PostReply> firstReplyList = resultPage.getRecords();


        List<PostReplyVo> result = this.getFinalPostReplyVoList(childrenReplyList, firstReplyList);

        return ResultObject.ok().putList(result, resultPage.getTotal());

    }


    public List<PostReplyVo> getFinalPostReplyVoList(List<PostReply> postChildrenReplyList) {
        if (postChildrenReplyList == null || postChildrenReplyList.isEmpty()) {
            return null;
        }
        PostReply oneReply = postChildrenReplyList.get(0);
        // 获取帖子的一级回复


        List<PostReply> parentReplyList =
                this.getFirstPostRepliesByPostIdAndPostType(
                        oneReply.getPostId(), oneReply.getPostType());

        return getFinalPostReplyVoList(postChildrenReplyList, parentReplyList);
    }

    public List<PostReplyVo> getFinalPostReplyVoList(List<PostReply> childrenReplyList, List<PostReply> parentReplyList) {
        if (parentReplyList == null || parentReplyList.isEmpty()) {
            return null;
        }

        List<PostReplyBaseInfo> parentReplyBaseInfoList = new ArrayList<>(parentReplyList.size());
        for (PostReply postReply : parentReplyList) {
            PostReplyBaseInfo postReplyBaseInfo = new PostReplyBaseInfo();
            BeanUtils.copyProperties(postReply, postReplyBaseInfo);
            parentReplyBaseInfoList.add(postReplyBaseInfo);
        }

        List<PostReplyVo> resultList = new ArrayList<>();
        for (PostReplyBaseInfo replyBaseInfo : parentReplyBaseInfoList) {
            PostReplyVo replyVo = new PostReplyVo();
            replyVo.setFirstReply(replyBaseInfo); // 设置一级回复
            List<PostReplyBaseInfo> childReplies = this.getChildrenReplyBaseInfoList(replyBaseInfo, childrenReplyList);
//            childReplies = childReplies.stream().sorted(Comparator.comparing(PostReplyBaseInfo::getGmtCreated).reversed()).collect(Collectors.toList()); // 降序
            if (childReplies != null && !childReplies.isEmpty()) {
                childReplies = childReplies.stream().sorted(Comparator.comparing(PostReplyBaseInfo::getGmtCreated)).collect(Collectors.toList()); // 升序
                replyVo.setChildReplies(childReplies);
            }
            resultList.add(replyVo);
        }
        if (resultList.isEmpty()) return null;
        return resultList;
    }

    public List<PostReplyBaseInfo> getChildrenReplyBaseInfoList(PostReplyBaseInfo parent, List<PostReply> postChildrenReplyList) {
        List<PostReply> tempList = new ArrayList<>(); // 临时列表
        tempList.addAll(postChildrenReplyList);

        List<PostReplyBaseInfo> resultList = new ArrayList<>();

        for (int i = 0; i < postChildrenReplyList.size(); i++) {
            // 当第i个回复为 当前 parentId 的子集回复时
            if (postChildrenReplyList.get(i).getParentId().equals(parent.getId())) {
                PostReply currentReply = postChildrenReplyList.get(i);
                PostReplyBaseInfo currentReplyBaseInfo = new PostReplyBaseInfo();
                BeanUtils.copyProperties(currentReply, currentReplyBaseInfo);
                currentReplyBaseInfo.setToUserId(parent.getUserId());
                resultList.add(currentReplyBaseInfo);
                tempList.remove(currentReply); // 将该回复移出列表
                List<PostReplyBaseInfo> childrenReplyBaseInfoList = getChildrenReplyBaseInfoList(currentReplyBaseInfo, tempList);
                if (childrenReplyBaseInfoList != null) {
                    resultList.addAll(childrenReplyBaseInfoList);
                }
            }
        }
        if (resultList.isEmpty()) {
            return null;
        } else {
            return resultList;
        }
    }

}
